package com.example.config;

import com.example.service.SuppliesService;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static com.example.config.SocketHandler.*;

@Slf4j
@Data
@Component
//@PropertySource("classpath:socket.properties")
@NoArgsConstructor
public class SocketServer implements Runnable {


    @Autowired
    private SuppliesService suppliesService;
    @Value("${port}")
    private Integer port;

    private boolean started;

    public SocketServer (Integer port){
        this.port = port;
    }
    //每当有一个客户端连接进来后，就启动一个单独的线程进行处理
    //创建一个可缓存线程池，如果线程池长度超过处理需要，可灵活回收空闲线程，若无可回收，则新建线程。
    private ExecutorService executorService = Executors.newCachedThreadPool();
    //创建一个定长线程池，可控制线程最大并发数，超出的线程会在队列中等待。
//    private ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
    // 缓存一个read事件中一个不完整的包，以待下次read事件到来时拼接成完整的包
    ByteBuffer cacheBuffer = ByteBuffer.allocate(100);
    boolean cache = false;



    public void start(){
        log.info("port: {}", this.port);
            SocketServer server =  new SocketServer(this.port);
            Thread t = new Thread(server);
            t.start();
    }

    @SneakyThrows
    @Override
    public void run() {
        try {
            ServerSocket serverSocket = new ServerSocket(this.port);
            started = true;
            while (started) {
                Thread.sleep(10);
                Socket socket = serverSocket.accept();
                //长连接
                socket.setKeepAlive(true);
                ClientSocket register = register(socket);
                log.info("客户端已连接，其Key值为：{}", register.getKey());
                if (register != null) {
                    executorService.submit(register);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
